using System;
using System.Collections.Generic;
using System.Text;

namespace SteeringBehaviors
{
    public class CarrierDefenseForce : TaskForce
    {
        #region PRIVATE MEMBERS

        int batchAmount;

        #endregion

        #region PROPERTIES

        /// <summary>
        /// Gets the carrier of this Carrier Defense Force
        /// </summary>
        /// <remarks>This will return null if no ships are present in this CDF.</remarks>
        public Carrier CarrierShip
        {
            get
            {
                if (Ships.Count != 0)
                    return (Carrier)Ships[0];
                return null;
            }
        }

        /// <summary>
        /// The amount of ships to produce at one time
        /// </summary>
        public int BatchAmount
        {
            get { return batchAmount; }
            set
            {
                if (value > 0)
                    batchAmount = value;
            }
        }

        #endregion

        #region CONSTRUCTORS

        /// <summary>
        /// Default constructor
        /// </summary>
        public CarrierDefenseForce()
        {
            WrapOutOfBounds = false;
            Random rand = new Random();
            Ships.Add(new Carrier());
            Ships[0].Position = new Microsoft.DirectX.Vector3(0f, 300f, 0f);
            Ships[0].Velocity = new Microsoft.DirectX.Vector3(Ships[0].MaxSpeed, 0f, 0f);
            Ships[0].DXColor = new Microsoft.DirectX.Direct3D.ColorValue(1f, 1f, 1f, 1f);
            StickToMinSpeed = false;
            BatchAmount = 1;
        }

        #endregion

        #region INTERFACE METHODS

        /// <summary>
        /// Gets a string representation of this CarrierDefenseForce
        /// </summary>
        /// <returns>a string representation of this CarrierDefenseForce</returns>
        public override string ToString()
        {
            //return base.ToString();
            return "Carrier Defense Force of " + Ships.Count + " ships.";
        }

        /// <summary>
        /// Adds the provided ship to this carrier defense force
        /// </summary>
        /// <param name="addMe">The ship to add to this carrier defense force</param>
        /// <remarks>This method will throw an exception if the first ship added is not a carrier.</remarks>
        public override void AddShip(Ship addMe)
        {
            if (Ships.Count > 0)
                base.AddShip(addMe);
            else
            {
                if (addMe.Type == "Carrier")
                    base.AddShip(addMe);
                else
                {
                    Exception e = new Exception("First ship in a Carrier Defense Force MUST be a Carrier.");
                    throw e;
                }
            }
        }

        /// <summary>
        /// Carrier defense forces can not be completely disbanded; this method will disband all containing ships that are not the Carrier
        /// </summary>
        /// <returns>list of disbanded ships</returns>
        public override List<Ship> Disband()
        {
            List<Ship> disbandedShips = new List<Ship>(Ships);
            disbandedShips.RemoveAt(0);
            while(Ships.Count > 1)
                DisbandShip(Ships[1].ID);
            return disbandedShips;
        }

        /// <summary>
        /// Attempts to remove the ship with the given id value
        /// </summary>
        /// <param name="id">given id value</param>
        /// <returns>this method ALWAYS returns null</returns>
        /// <remarks>the resources needed to build this ship will be restored to the Carrier ship</remarks>
        public override Ship DisbandShip(uint id)
        {
            for (int i = 0; i < Ships.Count; ++i)
            {
                if (Ships[i].ID == id)
                {
                    if (Ships[i].Type == "Carrier")
                        break;
                    else if (Ships[i].Type == "Fighter")
                    {
                        CarrierShip.Cargo += 25;
                        CarrierShip.Energy += 5f;
                    }
                    else if (Ships[i].Type == "Scout")
                    {
                        CarrierShip.Cargo += 15;
                        CarrierShip.Energy += 15f;
                    }
                    else if (Ships[i].Type == "Worker")
                    {
                        CarrierShip.Cargo += 5;
                        CarrierShip.Energy += 25f;
                    }
                    amountOfType[Ships[i].Type]--;
                    Ships.RemoveAt(i);
                    break;
                }
            }
            return null;
        }

        /// <summary>
        /// Gets the ship with the given id and removes it from this task force
        /// </summary>
        /// <param name="id">the given id</param>
        /// <returns>the ship with the given id</returns>
        /// <remarks>use this method to transfer a ship from this task force to another task force; this will return null if the ship is not found</remarks>
        public Ship RemoveShip(uint id)
        {
            Ship removedShip = null;
            for (int i = 0; i < Ships.Count; ++i)
            {
                if (Ships[i].ID == id)
                {
                    removedShip = Ships[i];
                    Ships.RemoveAt(i);
                    break;
                }
            }
            amountOfType[removedShip.Type]--;
            return removedShip;
        }

        /// <summary>
        /// Updates this carrier defense force
        /// </summary>
        /// <param name="delta">change in time since last Update call (in seconds)</param>
        public override void Update(float delta)
        {
            StickToLeader = true;
            AlignmentStrength = 0;
            base.Update(delta);
            if (CarrierShip.QueueStatus == Carrier.QUEUESTATUS.SHIPREADY)
            {
                int amount = 0;
                Ship shipToAdd = CarrierShip.DequeueShip(out amount);
                AddShip(shipToAdd);
                for (int i = 1; i < amount; ++i)
                    AddShip(shipToAdd.Clone());
            }
        }

        #endregion
    }
}
